#include "GameScene.h"

#include "GameDefine.h"


#ifdef GAME_USEKEYBOARD
#include <windows.h>
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0)
#define KEY_UP(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 0 : 1)
#endif

#include <cmath>
#include "Objects.h"

using namespace cocos2d;

CGameScene::CGameScene()
{
    memset(m_szTips, 0, sizeof(m_szTips));
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::onEnter()
{
	this->setIsTouchEnabled(true);
	this->setIsAccelerometerEnabled(true);

	m_pLayMain = CCLayer::node();
	addChild(m_pLayMain, 10);

	m_pLayUI = CCLayer::node();
	addChild(m_pLayUI, 20);

	InitBars();
    
    m_pLabel = CCLabelTTF::labelWithString("tips", "Terminal", 30);
    m_pLabel->setPosition(ccp(300, 50));
    m_pLayUI->addChild(m_pLabel);
    //strcpy(m_szTips, "应用程序正在初始化");
    //m_pLabel->setString(m_szTips);
    
	m_bFindMatch   = false;

#ifdef GAME_USERAKNET
	m_bGameStart   = false;
#else
	m_bGameStart = true;
#endif
	m_bServer      = false;



	m_player.InitState(this, m_pLayMain, 10, ccp(264, BOXER_Y_MIN + 260), &m_opponent);
	m_opponent.InitState(this, m_pLayMain, 10, ccp(SCREEN_WIDTH-264, SCREEN_HEIGHT - (BOXER_Y_MIN + 260)), &m_player, true);
	
	schedule(schedule_selector(CGameScene::Tick));
    CGameTimer::SetInterval(200);
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	//GCInit();
	//GCFindPlayer(2, 2, this);
    
    CAutoMutex::Init();
	char szID[ID_MAX_LENGTH];
	GCGetDeviceID(szID);
    m_pRaknet = CRaknetHelper::GetInstance();
	m_pRaknet->InitState(szID, ID_MAX_LENGTH, this);
	m_pRaknet->ConnectServer();
    
#endif

	CCLayer::onEnter();
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::onExit()
{
    m_pRaknet->StopReceiveThread();
    CAutoMutex::Destroy();
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::didAccelerate(CCAcceleration* pAccelerationValue)
{
	m_ptAcc.x = (float)pAccelerationValue->x;
	m_ptAcc.y = (float)pAccelerationValue->y;
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
	if(pTouches->count() < 1)
	{
		return;
	}

	int count = pTouches->count();

	CCTouch *pTouch = (CCTouch*)pTouches->anyObject();


#ifdef GAME_USERAKNET

	if(m_bGameStart)
	{
		if(count == 1)
		{
			if(CCRect::CCRectContainsPoint(CCRect(0, 0, SCREEN_WIDTH*0.5f, SCREEN_HEIGHT), m_pLayMain->convertTouchToNodeSpace(pTouch)))
			{
				if(m_bServer)
				{
                    CAutoMutex lock;
					m_player.AttackWithLeft();
				}
				else
				{
					ClientPacket p;
					p.m_command = COMMAND_ATTACK_LEFT;
					m_pRaknet->SendClientCommand(p);
					m_player.AttackWithLeft();
				}
			}
			else
			{
				if(m_bServer)
				{
                    CAutoMutex lock;
					m_player.AttackWithRight();
				}
				else
				{
					ClientPacket p;
					p.m_command = COMMAND_ATTACK_RIGHT;
					m_pRaknet->SendClientCommand(p);
					m_player.AttackWithRight();
				}
			}
		}
		else if(count == 2)
		{
			/*
			if(m_bServer)
			{
				m_player.Defense();
				m_raknet.SendServerInfo(GetCurGameInfo());
			}
			else
			{
				ClientPacket p;
				p.m_command = COMMAND_DEFANSE;
				m_raknet.SendClientCommand(p);
			}
			*/
		}

	}

#endif
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::PlayerLocalHurt()
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::PlayerOppoentHurt()
{

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::InitBars()
{
	for(int i=0; i<2; i++)
	{
		m_pSprBarBlankBlood[i]  = CCSprite::spriteWithFile("barBlank.png");
		m_pSprBarBlankSprite[i] = CCSprite::spriteWithFile("barBlank.png");
		m_pSprBarBlood[i]       = CCSprite::spriteWithFile("barBlood.png");
		m_pSprBarSprite[i]      = CCSprite::spriteWithFile("barSprite.png");

		m_pLayUI->addChild(m_pSprBarBlankBlood[i]);
		m_pLayUI->addChild(m_pSprBarBlankSprite[i]);
		m_pSprBarBlankBlood[i]->addChild(m_pSprBarBlood[i]);
		m_pSprBarBlankSprite[i]->addChild(m_pSprBarSprite[i]);
		
		m_pSprBarBlood[i]->setAnchorPoint(ccp(0, 0));
		m_pSprBarBlood[i]->setPosition(ccp(0, 0));
		m_pSprBarSprite[i]->setAnchorPoint(ccp(0, 0));
		m_pSprBarSprite[i]->setPosition(ccp(0, 0));
	}
	
	m_pSprBarBlankBlood[0]->setPosition(ccp(200, SCREEN_HEIGHT - 15));
	m_pSprBarBlankBlood[1]->setPosition(ccp(SCREEN_WIDTH - 200, SCREEN_HEIGHT - 15));
	m_pSprBarBlankSprite[0]->setPosition(ccp(200, SCREEN_HEIGHT - 45));
	m_pSprBarBlankSprite[1]->setPosition(ccp(SCREEN_WIDTH - 200, SCREEN_HEIGHT - 45));
}

void CGameScene::UpdateBars()
{

	m_pSprBarBlood[0]->setTextureRect(CCRect(0, 0, 200.0f * m_player.GetHp() / BOXER_HP_MAX, 18));
	m_pSprBarSprite[0]->setTextureRect(CCRect(0, 0, 200.0f * m_player.GetSprite() / BOXER_SPRITE_MAX, 18));

	m_pSprBarBlood[1]->setTextureRect(CCRect(0, 0, 200.0f * m_opponent.GetHp() / BOXER_HP_MAX, 18));
	m_pSprBarSprite[1]->setTextureRect(CCRect(0, 0, 200.0f * m_opponent.GetSprite() / BOXER_SPRITE_MAX, 18));

}

//---------------------------------------------------------------------------------------------------/
void CGameScene::ShowTimeDiff()
{
	timeval time;
	gettimeofday(&time	, NULL);
	static long lastTime = time.tv_sec * 1000 + time.tv_usec / 1000;
	long curTime = time.tv_sec * 1000 + time.tv_usec / 1000;
	CCLOG("localDelay %ld", curTime - lastTime);
	lastTime = curTime;
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::Tick(cocos2d::ccTime dt)
{
	if(m_bGameStart)
	{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        
        m_pLabel->setString(m_szTips);
        m_player.Update(dt);
        m_opponent.Update(dt);
        
        if(!CGameTimer::IsPrepared())
        {
            return;
        }
        
		if(m_bServer)
		{
            CAutoMutex lock;
            
			if(m_ptAcc.x > 0)
			{
				m_player.SetIsMoveLeft(false);
				//m_player.Move(ccp(BOXER_MOVE_DIST, 0));
			}
			else
			{
				m_player.SetIsMoveLeft(true);
				//m_player.Move(ccp(-BOXER_MOVE_DIST, 0));
			}

			if(m_ptAcc.y < -0.3f)
			{
				m_player.Dodge();
			}
			else
			{
				m_player.DodgeToNormal();
			}
		
			m_pRaknet->SendServerInfo(GetCurGameInfo());
		}
		else
		{
			ClientPacket p;

			if(m_ptAcc.x > 0)
			{
				p.m_command = COMMAND_MOVE_RIGHT;
                m_pRaknet->SendClientCommand(p);
                m_player.SetIsMoveLeft(false);
			}
			else
			{
				p.m_command = COMMAND_MOVE_LEFT;
                m_pRaknet->SendClientCommand(p);
                m_player.SetIsMoveLeft(true);
			}

			if(m_ptAcc.y < -0.3f)
			{
				p.m_command = COMMAND_DODGE;
                m_pRaknet->SendClientCommand(p);
                m_player.SetState(CBoxer::STATE_DODGE);
				m_player.Dodge();
			}
			else
			{
				p.m_command = COMMAND_DODGETONORMAL;
                m_pRaknet->SendClientCommand(p);
                m_player.SetState(CBoxer::STATE_NORMAL);
				m_player.DodgeToNormal();
			}
		}
#endif
        
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

	/*
	if(KEY_DOWN(0x57))
	{
		// w
		m_player.Move(ccp(0, BOXER_MOVE_DIST));
	}
	*/
	
	if(KEY_DOWN(0x53))
	{
		// s
		//m_player.Move(ccp(0, -BOXER_MOVE_DIST));
		m_player.Dodge();
	}
	else
	{
		m_player.DodgeToNormal();
	}

	if(KEY_DOWN(0x44))
	{
		// d
		m_player.Move(ccp(BOXER_MOVE_DIST, 0));
	}

	if(KEY_DOWN(0x41))
	{
		// a
		m_player.Move(ccp(-BOXER_MOVE_DIST, 0));
	}

	if(KEY_DOWN(0x4A))
	{
		// J
		m_player.AttackWithLeft();
	}

	if(KEY_DOWN(0x4B))
	{
		// K
		m_player.AttackWithRight();
	}

	/*
	if(KEY_DOWN(0x4C))
	{
		// L
		m_player.Defense();
	}
	*/

	if(KEY_DOWN(VK_UP))
	{
		//m_opponent.Move(ccp(0, BOXER_MOVE_DIST));
		m_opponent.Dodge();
	}
	else
	{
		m_opponent.DodgeToNormal();
	}

	/*
	if(KEY_DOWN(VK_DOWN))
	{
		m_opponent.Move(ccp(0, -BOXER_MOVE_DIST));
	}
	*/

	if(KEY_DOWN(VK_RIGHT))
	{
		m_opponent.Move(ccp(BOXER_MOVE_DIST, 0));
	}

	if(KEY_DOWN(VK_LEFT))
	{
		m_opponent.Move(ccp(-BOXER_MOVE_DIST, 0));
	}

	if(KEY_DOWN(VK_NUMPAD2))
	{
		m_opponent.AttackWithLeft();
	}

	if(KEY_DOWN(VK_NUMPAD1))
	{
		m_opponent.AttackWithRight();
	}

	/*
	if(KEY_DOWN(VK_NUMPAD3))
	{
		m_opponent.Defense();
	}
	*/

#endif
	}
}

//////////////////////NetworkDelegate/////////////////////
#ifdef GAME_USERAKNET

void CGameScene::connectServerSuccessed()
{
	CCLog("连接服务器成功，正在匹配房间");
	m_pRaknet->ConnectRandomRoom();
    //m_pLabel->setString("连接成功，正在匹配房间");
    strcpy(m_szTips, "连接成功，正在匹配房间");
}

void CGameScene::connectServerFailed()
{
    //m_pLabel->setString("服务器连接失败");
    strcpy(m_szTips, "服务器连接失败");
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::connectLost()
{
    //m_pLabel->setString("丢失连接");
    strcpy(m_szTips, "丢失连接");
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::opponentFound(const BoxerInfo &info)
{
	CCLog("已经发现对手，准备开始游戏");
    strcpy(m_szTips, "开始游戏");

	m_bGameStart = true;
	m_bServer = m_pRaknet->IsHost();
    if(!m_bServer)
    {
        m_player.SetIsClient(true);
        m_opponent.SetIsClient(true);
    }
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::receiveServerInfo(const GameInfo &info)
{
	UpdateCurGameInfo(info);
}   

//---------------------------------------------------------------------------------------------------/
void CGameScene::receiveCommand(const ClientPacket &packet)
{
	switch(packet.m_command)
	{
	case COMMAND_MOVE_UP:
		{
			//m_opponent.Move(ccp(0, -BOXER_MOVE_DIST));
		}
		break;
	case COMMAND_MOVE_DOWN:
		{
			//m_opponent.Move(ccp(0, BOXER_MOVE_DIST));
		}
		break;

	case COMMAND_MOVE_LEFT:
		{
			//m_opponent.Move(ccp(BOXER_MOVE_DIST, 0));
			m_opponent.SetIsMoveLeft(true);
		}
		break;

	case COMMAND_MOVE_RIGHT:
		{
			//m_opponent.Move(ccp(-BOXER_MOVE_DIST, 0));
			m_opponent.SetIsMoveLeft(false);
		}
		break;

	case COMMAND_ATTACK_LEFT:
		{
			m_opponent.AttackWithLeft();
		}
		break;

	case COMMAND_ATTACK_RIGHT:
		{
			m_opponent.AttackWithRight();
		}
		break;

	case COMMAND_DEFANSE:
		{
			m_opponent.Defense();
		}
		break;

	case COMMAND_DEFANSECANCLE:
		{
			m_opponent.DefenseToNormal();
		}
		break;
	case COMMAND_DODGE:
		{
			m_opponent.Dodge();
		}
		break;
	case COMMAND_DODGETONORMAL:
		{
			m_opponent.DodgeToNormal();
		}
		break;
	}
}

//---------------------------------------------------------------------------------------------------/
const GameInfo &CGameScene::GetCurGameInfo()
{
    CAutoMutex lock;
	// 服务器获取本地逻辑结果
	static GameInfo info;
    
	info.m_action[0] = m_player.GetAction();
	info.m_action[1] = m_opponent.GetAction();

	info.m_state[0] = m_player.GetState();
	info.m_state[1] = m_opponent.GetState();

	info.m_hp[0] = m_player.GetHp();
	info.m_hp[1] = m_opponent.GetHp();

	info.m_sprite[0] = m_player.GetSprite();
	info.m_sprite[1] = m_opponent.GetSprite();

	info.m_xPos[0] = m_player.GetPostion().x;
	info.m_xPos[1] = m_opponent.GetPostion().x;

	info.m_yPos[0] = m_player.GetPostion().y;
	info.m_yPos[1] = m_opponent.GetPostion().y;

	return info;
}

//---------------------------------------------------------------------------------------------------/
void CGameScene::UpdateCurGameInfo(const GameInfo &info)
{
	// 客户端会接受此信息来更新游戏
    
    
	CCLOG("xPos1 %f, yPos1 %f xPos2 %f, yPos2 %f", info.m_xPos[0], info.m_yPos[0], info.m_xPos[1], info.m_yPos[1]);
	m_player.SetHp(info.m_hp[1]);
	m_opponent.SetHp(info.m_hp[0]);

	m_player.SetSprite(info.m_sprite[1]);
	m_opponent.SetSprite(info.m_sprite[0]);

	m_player.SetPosition(ccp(SCREEN_WIDTH - info.m_xPos[1], SCREEN_HEIGHT - info.m_yPos[1]));
	m_opponent.SetPosition(ccp(SCREEN_WIDTH - info.m_xPos[0], SCREEN_HEIGHT - info.m_yPos[0]));

	/*
	switch(info.m_state[0])
	{
	case CBoxer::STATE_RIGID_LEFT:
		{
			m_opponent.ShowLeftAttack();
		}
		break;

	case CBoxer::STATE_RIGID_RIGHT:
		{
			m_opponent.ShowRightAttack();
		}
		break;

	case CBoxer::STATE_DEFENSE:
		{
			m_opponent.ShowDefense();
		}
		break;
	case CBoxer::STATE_NORMAL:
		{
			m_opponent.ResetToNormal();
		}
    case CBoxer::STATE_DODGE:
        {
            m_opponent.ShowDodge();
        }
		break;
	}

	switch(info.m_state[1])
	{
	case CBoxer::STATE_RIGID_LEFT:
		{
			m_player.ShowLeftAttack();
		}
		break;

	case CBoxer::STATE_RIGID_RIGHT:
		{
			m_player.ShowRightAttack();
		}
		break;

	case CBoxer::STATE_DEFENSE:
		{
			m_player.ShowDefense();
		}
		break;
	case CBoxer::STATE_NORMAL:
		{
			m_player.ResetToNormal();
		}
		break;
    case CBoxer::STATE_DODGE:
        {
            m_player.ShowDodge();
        }
        break;
	}
	*/
    
    UpdateBars();
}
#endif


